import { FC, ReactElement, useEffect, useState } from "react";
import styled from "styled-components";
import { flexCenter } from "../components/BUI/styled";
import { getAllBlogTags, ITag } from "../api/tagApi";
import { useRouter } from "next/router";
import SEO from "../layout/SEO";

interface IProps {}

// const canvasWidth = 1000;
// const canvasHeight = 600;

const randomColor = () =>
  `#${Math.round(Math.random() * 0xffffff).toString(16)}`;

const randomNum = (min: number, max: number) =>
  Math.round(Math.random() * (max - min)) + min;

function randomOne<T>(x: T, y: T): T {
  return Math.random() > 0.5 ? x : y;
}

interface Tag {
  name: string;
  count: number;
}

const TagCanvas: FC<IProps> = (): ReactElement => {
  const { push } = useRouter();
  const [tags, setTags] = useState<ITag[]>([]);

  useEffect(() => {
    getAllBlogTags().then(({ data }) => {
      console.log(data);
      if (data) setTags(data);
    });
  }, []);

  useEffect(() => {
    if (!tags.length) return;
    const canvas = document.getElementById("canvas") as HTMLCanvasElement;
    const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;

    const canvasWidth = document.body.offsetWidth;
    const canvasHeight = document.body.offsetHeight;

    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    const minR = 20;
    const maxR = 40;
    class Boll {
      r: number;
      x: number;
      y: number;
      xDir: number;
      yDir: number;
      space: number;
      fillStyle: string;
      tag: Tag;
      index: number;

      constructor(tag: Tag, index: number) {
        const count = tag.count * 5;
        //随机大小
        // this.r = randomNum(20, 40);
        this.r = count < minR ? minR : count > maxR ? maxR : minR;
        //随机位置
        this.x = randomNum(this.r, canvasWidth - this.r);
        this.y = randomNum(this.r, canvasHeight - this.r);
        //随机方向
        this.xDir = randomOne(1, -1);
        this.yDir = randomOne(1, -1);
        //随机速度
        this.space = randomNum(0.5, 2);
        //随机颜色
        this.fillStyle = randomColor();
        this.tag = tag;
        this.index = index;
        this.show();
      }

      show() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        ctx.fillStyle = this.fillStyle;
        ctx.fill();
        ctx.closePath();
        this.run();
      }

      renderText() {
        ctx.beginPath();
        ctx.font = `${this.r / 2}px 微软雅黑`;
        ctx.fillStyle = "#fff";
        //剧中
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(
          `${this.tag.name}(${this.tag.count})`,
          this.x,
          this.y,
          this.r * 1.8
        ); //实心文本
        ctx.closePath();
      }

      private run() {
        if (this.x <= this.r || this.x >= canvasWidth - this.r) {
          this.xDir = -this.xDir;
          this.fillStyle = randomColor();
        }
        if (this.y < this.r || this.y > canvasHeight - this.r) {
          this.yDir = -this.yDir;
          this.fillStyle = randomColor();
        }

        this.x += this.xDir * this.space;
        this.y += this.yDir * this.space;
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        this.renderText();
      }
    }

    const bollArr: Boll[] = [];
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);

    tags.forEach((tag, index) => {
      bollArr.push(new Boll(tag, index));
    });

    (function star() {
      ctx.clearRect(0, 0, canvasWidth, canvasHeight);
      bollArr.forEach(boll => {
        boll.show();
      });
      setTimeout(() => {
        star();
      }, 30);
    })();

    canvas.addEventListener("click", e => {
      const { offsetX, offsetY } = e;
      const clickTags = bollArr.filter(({ x, y, r, tag, index }) => {
        const v = offsetX > x - r && offsetX < x + r;
        const h = offsetY > y - r && offsetY < y + r;
        if (v && h) return { tag, index };
      });
      if (!clickTags.length) return;
      //点击小球
      //没有重叠情况
      let tagName = "";
      if (clickTags.length === 1) {
        tagName = clickTags[0].tag.name;
      } else {
        const [{ tag }] = clickTags.sort((a, b) => b.index - a.index);
        tagName = tag.name;
      }
      push(`/blogList?tag=${tagName}`);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tags]);

  return (
    <Container>
      <SEO title="标签墙" />
      {tags.length ? (
        <Canvas
          id="canvas"
          //  width={canvasWidth}
          //  height={canvasHeight}
        />
      ) : null}
    </Container>
  );
};

export default TagCanvas;

const Canvas = styled.canvas``;

const Container = styled.div`
  height: 100vh;
  ${flexCenter};
`;
